/*
 *  linmigrate - debian specific implementation
 *
 *  Copyright (C) 2011 by Volodymyr M. Shcherbyna <volodymyr@shcherbyna.com>
 *
 *      This file is part of linmigrate.
 *
 *  linmigrate is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  linmigrate is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with linmigrate.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "debianhandler.h"

/**   C'tor of the object

    * @return initialized object
*/
CDebianHandler::CDebianHandler(QTextStream & console) : IDistributionHandler(console)
{
}

/**   Getting the type of distribution being handling

    * @return IDistribution
*/
IDistribution CDebianHandler::Identify()
{
    return Debian;
}

/**   Exporting debian distribution

    * @return boolean
*/
int CDebianHandler::Export(ExportOptions & options)
{
    QString szExportDirName = "./export";
    QString szExportDir;
    QDir    ExportDir;

    m_console << "Handling export action." << endl;

    szExportDir = ExportDir.absolutePath();
    szExportDir += "/export";

    m_console << "Cleaning old data from: " << szExportDir;

    if (CleanDirectory(szExportDir) == true)
    {
        m_console << " : OK" << endl;
    }
    else
    {
        m_console << " : Failure. Can't clear old data folder. Abort." << endl;

        return (0x01);
    }

    /// try to see if there is enough space in /tmp to hold export
    //{
    //    QString szCheckSize = "/home/v/OS";
    //    GetFreeDiskSpace(szCheckSize);
    //}

    if (ExportDir.mkdir("export") == true)
    {
        QProcess dpkg;

        m_console << "Getting list of installed packages: ";

        dpkg.start("dpkg", QStringList() << "--get-selections");

        if (!dpkg.waitForFinished())
        {
            m_console << "Failure. Abort." << endl;

            return (0x02);
        }

        if (dpkg.exitCode() != 0)
        {
            m_console << "Failure. Abort." << endl;

            return (0x03);
        }

        m_console << "OK" << endl;
        m_console << "Storing list of installed packages: ";

        QByteArray result = dpkg.readAll();
        bool bFileWritten = false;

        if (result.size())
        {
            QString szPath = ExportDir.absolutePath();
            szPath += "/export/packages.txt";

            QFile file(szPath);

            if (file.open(QIODevice::WriteOnly | QIODevice::Text))
            {
                file.write(result); bFileWritten = true;
            }
        }

        m_console << (bFileWritten ? "OK" : "Failure. Abort.") << endl;

        if (bFileWritten == false)
        {
            return (0x04);
        }

        m_console << "Storing /etc/hosts file: ";
        bFileWritten = CopyHostsFile(szExportDir);
        m_console << (bFileWritten ? "OK" : "Failure. Abort.") << endl;

        if (bFileWritten == false)
        {
            return (0x05);
        }

        m_console << "Storing /etc/X11/xorg.conf file: ";
        bFileWritten = CopyXorgFile(szExportDir);
        m_console << (bFileWritten ? "OK" : "Failure.") << endl;

        if (bFileWritten == false)
        {
            //return (0x08);
        }

        m_console << "Storing /etc/rc.local file: ";
        bFileWritten = CopyRCLocalFile(szExportDir);
        m_console << (bFileWritten ? "OK" : "Failure.") << endl;

        if (bFileWritten == false)
        {
            //return (0x08);
        }

        m_console << "Storing /etc/fstab file: ";
        bFileWritten = CopyFstabFile(szExportDir);
        m_console << (bFileWritten ? "OK" : "Failure. Abort.") << endl;

        if (bFileWritten == false)
        {
            return (0x06);
        }

        //char *szUser = getenv("USER");
        m_console << "Copying files from /home/. It can take a while..." << endl; sleep(2);
        bFileWritten = CopyDirectory("/home", (szExportDir + "/home"), options.bExcludeSymlinks, szExportDir);

        if (bFileWritten == false)
        {
            m_console << "Copying home directories failed. Abort" << endl;

            return (0x07);
        }

        m_console << "Compressing resulting directory: ";

        bFileWritten = CompressDirectory(szExportDirName);
        m_console << (bFileWritten ? "OK" : "Failure. Abort.") << endl;

        if (bFileWritten == false)
        {
            m_console << "Compressing data directory failed. Abort." << endl;

            return (0x08);
        }

        m_console << "Everything went okay. You can find your compressed file here: " << szExportDir << ".tar" << endl;

        CleanDirectory(szExportDir);

        return (0x00);
    }
    else
    {
        m_console << "Can't create data folder. Abort." << endl;

        return (0x09);
    }

    return (0x0a);
}

/**   Importing debian distribution

    * @return 0 in case of success, or error number
*/
int CDebianHandler::Import(ImportOptions & options)
{
    //options.szImportFile = "/home/v/OS/linmigrate/export.tar.gz";

    m_console << "Handling import action. Importing file: " << options.szImportFile << endl;
    m_console << "Uncompressing file: ";

    QString szTmp = "/tmp/";

    if (UnCompressDirectory(options.szImportFile, szTmp) == true)
    {
        szTmp += "export/";
        m_console << "OK" << endl;

        // 1. Copy hosts file
        m_console << "Restoring hosts file: ";

        if (CopyFile(szTmp + "hosts", "/etc/hosts") == false)
        {
            m_console << "failed. Abort. Are you running as root?" << endl;

            return (0x02);
        }

        m_console << "OK" << endl;

        // 2. Copy fstab file

        m_console << "Restoring fstab file: ";

        if (CopyFile(szTmp + "fstab", "/etc/fstab") == false)
        {
            m_console << "failed. Abort. Are you running as root?" << endl;

            return (0x03);
        }

        m_console << "OK" << endl;

        // 3. Copy init.rc file

        m_console << "Restoring init.rc file: ";

        if (CopyFile(szTmp + "rc.local", "/etc/rc.local") == false)
        {
            m_console << "failed. Abort. Are you running as root?" << endl;

            return (0x03);
        }

        m_console << "OK" << endl;

        const QString szHomeDir = "/home/";
        const QString szHomeDirCpyFrom = szTmp + "home";
        QString szFakeString = "";	

	m_console << "OK" << endl;
	m_console << "Restoring /home directory: ";

        QDir srcDir(szHomeDirCpyFrom);

        foreach(const QFileInfo & info, srcDir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot))
        {
            // 3. cleaning /home dir ...
            m_console << "Cleaning " << szHomeDir + info.fileName() << "directory" << endl;

            if (CleanDirectory(szHomeDir + info.fileName()) == false)
            {
                m_console << "failed. Abort. Are you running as root?" << endl;

                return (0x04);
            }

            if (CopyDirectory(info.absoluteFilePath(), szHomeDir + info.fileName(), true, szFakeString) == false)
            {
                m_console << "failed. Abort. Are you running as root?" << endl;

                return (0x05);
            }
        }        

	m_console << "OK" << endl;
    }
    else
    {
        m_console << "failed. Abort." << endl;

        return (0x01);
    }

    return 0;
}
